from django.contrib.auth import authenticate
from rest_framework import serializers
from rest_framework import exceptions
from django.contrib.auth.models import User
import re


class UserRegisterSerializer(serializers.ModelSerializer):
    # username = serializers.CharField()
    # password = serializers.CharField(write_only=True)
    confirm_password = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = [
            'id',
            'username',
            'email',
            'password',
            'confirm_password',
        ]
        extra_kwargs = {
            'password': {'write_only': True}
        }

    def create(self, validated_data):
        user = User.objects.create_user(**validated_data)
        return user

    default_error_messages = {
        'password_error': '两次密码输入不正确',
    }

    # 此序列化器主要是对注册字段的校验，所以重写了validate方法
    def validate(self, attrs):
        if User.objects.filter(username=attrs['username']):
            raise exceptions.ParseError(detail='用户名已存在')
        if not re.match(r'^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$', attrs['email']):
            raise exceptions.ParseError(detail='邮箱格式错误')
        if not 6 <= len(attrs['password']) <= 18:
            raise exceptions.ParseError(detail='密码要在6-18位之间')
        if attrs.get('password') != attrs.get('confirm_password'):
            raise exceptions.ParseError(detail='两次密码输入不相同')
        del attrs['confirm_password']  # 删除重复密码
        return attrs


class UserLoginSerializer(serializers.Serializer):
    username = serializers.CharField(required=True)
    password = serializers.CharField(required=True)

    default_error_messages = {
        'inactive_account': '用户已被禁用',
        'invalid_credentials': '账号或密码无效'
    }

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.user = None

    def validate(self, attrs):
        self.user = authenticate(username=attrs.get("username"), password=attrs.get('password'))
        if self.user:
            if not self.user.is_active:
                raise exceptions.ParseError(detail='用户已被禁用')
            return attrs
        else:
            raise exceptions.ParseError(detail='账号或密码无效')
